Skip to content

feat(fabric): add NATS EventFabric + RunnerFabric seams (RIG-3107) - #877

Open
rigel-mintaka wants to merge 1 commit into
compass-managed/rig-3107-go-floorfrom
compass-managed/rig-3107-nats-fabric
Open

feat(fabric): add NATS EventFabric + RunnerFabric seams (RIG-3107)#877
rigel-mintaka wants to merge 1 commit into
compass-managed/rig-3107-go-floorfrom
compass-managed/rig-3107-nats-fabric

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

This PR is part of a stack containing 2 PRs:

  1. main
  2. chore(go): raise module floor to 1.26 + absorb modernize sweep (RIG-3107) #876
  3. "feat(fabric): add NATS EventFabric + RunnerFabric seams (RIG-3107)" (this PR)

First code slice of the T3 NATS fabric (frozen in RIG-2861): a new go/internal/fabric package providing the two transport seams the comms and runner planes cut over to, over a single NATS connection. Stacked on the go-1.26 floor bump (its own PR) that the nats-server test dependency requires.

EventFabric — durable comms fan-out on JetStream. Publish(ctx, subject, EventRef) / Subscribe(ctx, subject, func(EventRef)). Carries a compact EventRef (tenant + kind + row id) as an at-least-once reference, never the payload, so JetStream stays a transport rather than a second store; subscribers re-read Postgres by row id. MsgID = sha256 of the length-prefixed ref for dedup within the Duplicates window; app-level DLQ via Term() at the delivery budget.

RunnerFabric — best-effort runner control on core NATS. SendCommand(ctx, runnerID, *SessionsResponse) / Events(ctx) (<-chan RunnerEvent, error); offline runners are recovered by the delivery cursor sweep, not by broker durability.

One Fabric implements both seams over one nats.Conn. Lazy stream ensure (the frozen New carries no context, so the topology call derives its ctx from the first Publish/Subscribe). Per-subject durable consumer named comms-+sha256(subject) — injective, unlike a ._ substitution which would collapse two subjects onto one shared consumer. Close registers a StatusChanged(nats.CLOSED) listener before draining so it observes connection teardown directly rather than through a clobberable ClosedHandler. Full subject grammar + JetStream config in SUBJECTS.md beside the package.

Subjects: compass.<tenant>.comms.<kind>, compass.runner.<runner_id>.cmd, compass.runner.events (queue-grouped), client.<sessionID>.

Spec-impact: none. Refs RIG-3107

@linear-code

linear-code Bot commented Sep 4, 2026

Copy link
Copy Markdown

RIG-3107

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-managed-rig-3107-nat.compass-eng-docs.pages.dev

Deployed from compass-managed/rig-3107-nats-fabric at 66a1126.

Changed pages:

@rigel-mintaka
rigel-mintaka force-pushed the compass-managed/rig-3107-nats-fabric branch from 12612dd to d9db404 Compare September 4, 2026 23:42
@rigel-mintaka
rigel-mintaka marked this pull request as ready for review September 4, 2026 23:43
First code slice of the T3 NATS fabric (frozen in RIG-2861): a new `go/internal/fabric` package providing the two transport seams the comms and runner planes cut over to, over a single NATS connection. Stacked on the go-1.26 floor bump (its own PR) that the nats-server test dependency requires.

**EventFabric** — durable comms fan-out on JetStream. `Publish(ctx, subject, EventRef)` / `Subscribe(ctx, subject, func(EventRef))`. Carries a compact `EventRef` (tenant + kind + row id) as an at-least-once reference, never the payload, so JetStream stays a transport rather than a second store; subscribers re-read Postgres by row id. MsgID = sha256 of the length-prefixed ref for dedup within the Duplicates window; app-level DLQ via `Term()` at the delivery budget.

**RunnerFabric** — best-effort runner control on core NATS. `SendCommand(ctx, runnerID, *SessionsResponse)` / `Events(ctx) (<-chan RunnerEvent, error)`; offline runners are recovered by the delivery cursor sweep, not by broker durability.

One `Fabric` implements both seams over one `nats.Conn`. Lazy stream ensure (the frozen `New` carries no context, so the topology call derives its ctx from the first Publish/Subscribe). Per-subject durable consumer named `comms-`+sha256(subject) — injective, unlike a `.`→`_` substitution which would collapse two subjects onto one shared consumer. Close registers a `StatusChanged(nats.CLOSED)` listener before draining so it observes connection teardown directly rather than through a clobberable ClosedHandler. Full subject grammar + JetStream config in `SUBJECTS.md` beside the package.

Also ignores the golangci-lint `-review` cache dir (`/go/.golangci-cache-review/`) alongside the existing `.golangci-cache` entry, so the review lane's per-workspace cache is never committed.

Subjects: `compass.<tenant>.comms.<kind>`, `compass.runner.<runner_id>.cmd`, `compass.runner.events` (queue-grouped), `client.<sessionID>`.

Spec-impact: none. Refs RIG-3107

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka
rigel-mintaka force-pushed the compass-managed/rig-3107-nats-fabric branch from d9db404 to 66a1126 Compare September 5, 2026 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant